package landyer.tools.jdbcGenerator;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import groovy.lang.Writable;
import groovy.text.GStringTemplateEngine;
import groovy.text.Template;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * User: landy
 * Date: 13-12-13
 * Time: 下午7:35
 */
public class ModleGenerator {
    private final boolean onlySave;
    private List<ColumnBean> columnBeans;
    private String clsName;
    private String tableName;

    public ModleGenerator(List<ColumnBean> columns, String tableName,boolean onlySave) {
        this.columnBeans = columns;
        this.tableName=tableName;
        this.clsName = RenameField.getClassName(tableName);
        this.onlySave=onlySave;
    }
    public ColumnBean getPK(){
        for(ColumnBean cb:this.columnBeans){
            if(cb.isPrimaryKey()){
                return cb;
            }
        }
        return null;
    }
    public String genertorMapper() {
        StringBuffer sb = new StringBuffer();
        sb.append("import org.springframework.jdbc.core.RowMapper;\n" +
                "import java.sql.ResultSet;\n" +
                "import java.sql.SQLException;\n\n" +
                "public class ")
                .append(clsName)
                .append("RowMapper implements RowMapper<")
                .append(clsName)
                .append("> {\n")
                .append("\n")
                .append("    @Override\n")
                .append("    public ")
                .append(clsName)
                .append(" mapRow(ResultSet resultSet, int i) throws SQLException {\n")
                .append("        ")
                .append(clsName)
                .append(" bean=new ")
                .append(clsName)
                .append("();\n");
        for (ColumnBean cb : columnBeans) {
            sb.append("        bean."+cb.getSetterName()+"(resultSet."+cb.getResultSetGetterName()+"(\""+cb.getName()+"\"));\n");
        }
        sb.append("        return bean;\n")
                .append("    }\n")
                .append("}");
        return sb.toString();
    }
    private DateFormat fmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public String genertorDao(String packageName) throws IOException, ClassNotFoundException {
        GStringTemplateEngine engine = new GStringTemplateEngine();

        String name = "/template/dao.gsp";
        if (onlySave) {
            name = "/template/daoSave.gsp";
        }
        Template tmpt = engine.createTemplate(ModleGenerator.class.getResource(name));
        Map<String,Object> maps= Maps.newHashMap();
        ColumnBean pk=getPK();
        maps.put("tableName",this.tableName);
        maps.put("className",this.clsName);
        maps.put("cbs",this.columnBeans);
        maps.put("sql_insertAll",genertorInsertSql());
        maps.put("sql_updateAll",genertorUpdateByPKSql());
        maps.put("pkColumn",pk.getName());
        maps.put("pkSetter",pk.getSetterName());
        maps.put("packageName",packageName);
        maps.put("nowDatetime",fmt.format(Calendar.getInstance().getTime()));
        Writable make = tmpt.make(maps);
        return make.toString();
    }
    public String genertorPojo(String packageName) throws IOException, ClassNotFoundException {
        GStringTemplateEngine engine = new GStringTemplateEngine();

        Template tmpt = engine.createTemplate(ModleGenerator.class.getResource("/template/pojo.gsp"));
        Map<String,Object> maps=Maps.newHashMap();
        maps.put("tableName", this.tableName);
        maps.put("className",this.clsName);
        maps.put("cbs",this.columnBeans);
        maps.put("packageName",packageName);
        maps.put("nowDatetime",fmt.format(Calendar.getInstance().getTime()));
        Writable make = tmpt.make(maps);
        return make.toString();
    }
    public String genertorInsertSql() {
        StringBuffer sb = new StringBuffer();
        List<String> columns= Lists.newArrayList();
        List<String> fields=Lists.newArrayList();
        for(ColumnBean cb:this.columnBeans){
            if(cb.isPrimaryKey())continue;
            columns.add(cb.getName());
            fields.add(":"+cb.getAdjustName());
        }

        sb.append("insert into "+this.tableName+" ("+Joiner.on(",").join(columns)+") values ("+Joiner.on(",").join(fields)+")");
        return sb.toString();
    }
    public String genertorUpdateSql() {
        StringBuffer sb = new StringBuffer();
        List<String> sets= Lists.newArrayList();
        List<String> wheres= Lists.newArrayList();
        for(ColumnBean cb:this.columnBeans){
            wheres.add(cb.getName()+"=:"+cb.getAdjustName());
            if(cb.isPrimaryKey()) continue;
            sets.add(cb.getName()+"=:"+cb.getAdjustName());
        }

        sb.append("update "+this.tableName+" set "+Joiner.on(",").join(sets)+" where "+Joiner.on(",").join(wheres));
        return sb.toString();
    }
    public String genertorUpdateByPKSql() {
        StringBuffer sb = new StringBuffer();
        List<String> sets= Lists.newArrayList();
        String where="";
        for(ColumnBean cb:this.columnBeans){
            if(cb.isPrimaryKey()){
                where+=cb.getName()+"=:"+cb.getAdjustName();
            }else{
                sets.add(cb.getName()+"=:"+cb.getAdjustName());
            }

        }

        sb.append("update "+this.tableName+" set "+Joiner.on(",").join(sets)+" where "+where);
        return sb.toString();
    }
    public String genertorSelectSql() {
        StringBuffer sb = new StringBuffer();
        List<String> sets= Lists.newArrayList();
        List<String> columns= Lists.newArrayList();
        for(ColumnBean cb:this.columnBeans){
            columns.add(cb.getName());
            sets.add(cb.getName()+"=:"+cb.getAdjustName());
        }

        sb.append(String.format("select %s from %s where %s",Joiner.on(",").join(columns),this.tableName,Joiner.on(",").join(sets)));
        return sb.toString();
    }
    public String genertorDeleteSql() {
        StringBuffer sb = new StringBuffer();
        List<String> sets= Lists.newArrayList();
        for(ColumnBean cb:this.columnBeans){
            sets.add(cb.getName()+"=:"+cb.getAdjustName());
        }

        sb.append(String.format("delete from %s where %s",this.tableName,Joiner.on(",").join(sets)));
        return sb.toString();
    }


    public String getclassName() {
        return this.clsName;
    }
}
